package com.sboot.shiro.common.shiro;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.sboot.shiro.biz.sys.user.po.SysPermission;
import com.sboot.shiro.biz.sys.user.service.SysPermissionService;
import com.sboot.shiro.common.beans.ReturnData;

public class ResourceAccessFilter extends AccessControlFilter {

	@Autowired
	private SysPermissionService sysPermissionService;

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		// 1.获取当前用户，如果没有认证返回false
		Subject subject = super.getSubject(request, response);
		if (!subject.isAuthenticated()) {
			return false;
		}

		// 2.获取当前URL
		String url = super.getPathWithinApplication(request);
		// 3.根据当前URL 获得URL所需要的权限
		SysPermission sysPermission = new SysPermission();
		sysPermission.setUrl(url);
		List<SysPermission> perms = sysPermissionService.getPermissionsByConditions(sysPermission);
		if (perms == null || perms.size() == 0) { // 该资源不需要任何权限
			return true;
		} else {
			String[] permissionsArr = new String[perms.size()];
			for (int i = 0; i < permissionsArr.length; i++) {
				permissionsArr[i] = perms.get(i).getCode();
			}
			// 4.判断用户是否拥有该权限
			boolean[] results = subject.isPermitted(permissionsArr);
			if (results == null || results.length == 0) {
				return false;
			}

			for (boolean r : results) {
				if (r == true) {
					return true;
				}
			}
			return false;
		}
	}

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		Subject subject = getSubject(request, response);
		if (!subject.isAuthenticated()) {// 未登录，或超时
			if (this.isAjaxRequest((HttpServletRequest)request)) {
				ReturnData retData = ReturnData.WARNING("超时", null);
				write((HttpServletResponse)response, JSON.toJSONString(retData));
			} else {
				WebUtils.issueRedirect(request, response, "/timeout");
			}
		} else {// 没有权限
			if (this.isAjaxRequest((HttpServletRequest)request)) {
				ReturnData retData = ReturnData.WARNING("没有权限", null);
				write((HttpServletResponse)response, JSON.toJSONString(retData));
			} else {
				WebUtils.issueRedirect(request, response, "/403");
			}
		}
		return false;
	}

	
	/**
	 * 判断是否ajax 请求
	 * @param request
	 * @return
	 */
	private boolean isAjaxRequest(HttpServletRequest request) {
		String requestType = request.getHeader("X-Requested-With");
		return requestType != null && requestType.equals("XMLHttpRequest");
	}
	
	private void write(HttpServletResponse response, String message) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println(message);
        out.flush();
        out.close();
    }
}
